<?php

namespace App\Console\Commands;

use App\Dep\ContentDep;
use App\Dep\ContentLogDep;
use App\Dep\ReleaseTaskDep;
use App\Enum\ContentEnum;
use App\Enum\ReleaseTaskEnum;
use Illuminate\Console\Command;
use App\Service\ReleaseService;

class ReleaseCmd extends Command
{
    public $pid;
    public $signature = 'content:release {--pid=}';

    public function handle(){

        $this->pid = $this->option('pid');

//        $lockFile = base_path("/app/Console/Commands/lock-{$this->pid}.log");
//        if(file_exists($lockFile)){
//            $this->log("process is running: {$this->pid}");
//            return false;
//        }
//        file_put_contents($lockFile,time());
//        while (true) {
//            $this->handleJob();
//            $currentTime = time();
//            $beginTime = file_get_contents($lockFile);
//            if($currentTime - $beginTime > 50){
//                unlink($lockFile);
//                $this->log("process is out of time,restart: {$this->pid}");
//                return false;
//            }
//            sleep(10);
//        }
        $this->handleJob();
    }

    private function handleJob(){

        $releaseTaskDep = new ReleaseTaskDep();

        $this->log('begin');

        $resDealing = $releaseTaskDep->firstDealing($this->pid);
        if($resDealing){
            $this->log("task is running");
            return false;
        }

        $resWaitTask = $releaseTaskDep->getWait($this->pid);
        if($resWaitTask->isEmpty()){
            $this->log("have no wait task");
            return false;
        }

        $releaseService = new ReleaseService();
        $resWaitTask->each(function($task) use ($releaseService){
            $current = date('Y-m-d H:i:s');
            if($task->time_at > $current){
                $this->log("this is time job, current:{$current} time_at:{$task->time_at} content_id:{$task->content_id}");
                return true;
            }

            $this->log("deal one {$task->content_id}");
            $this->taskDealing($task->content_id,$task->id);

            $resRelease =  $releaseService->release($task->content_id);
            if(!$resRelease['status']){
                $this->log("release failed {$task->content_id}",['id' => $task->content_id,'msg' => $resRelease['msg']]);
                $this->taskFail($task->content_id,$task->id,$resRelease['msg']);
                return true;
            }
            $this->log("release done {$task->content_id}");
            $this->taskDone($task->content_id,$task->id,$resRelease['data']);
        });

    }

    private function log($msg,$context = []){
        $this->info("release fail: {$msg}");
        log_daily("release-{$this->pid}")->info($msg,$context);
    }

    private function taskDealing($contentId,$taskId){

        $releaseTaskDep = new ReleaseTaskDep();
        $data = [
            'status' => ReleaseTaskEnum::STATUS_DEALING,
            'deal_at' => date("Y-m-d H:i:s"),
        ];

        $releaseTaskDep->edit($taskId,$data);
    }

    public function taskDone($contentId,$taskId,$releaseData){
        $releaseTaskDep = new ReleaseTaskDep();
        $data = [
            'status' => ReleaseTaskEnum::STATUS_DONE,
            'done_at' => date('Y-m-d H:i:s'),
        ];

        $releaseTaskDep->edit($taskId,$data);

        $contentDep = new ContentDep();
        $contentData = [
            'status' =>  ContentEnum::STATUS_RELEASE,  //已发布
            'platform_id' => $releaseData['platform_id']
        ];

        $contentDep->edit($contentId,$contentData);

        $contentLogDep = new ContentLogDep();
        $logData = [
            'content_id' => $contentId,
            'description' => "发布成功",
        ];
        $contentLogDep->add($logData);

    }

    public function taskFail($contentId,$taskId,$msg){

        $contentDep = new ContentDep();
        $resDetail = $contentDep->first($contentId);

        $releaseTaskDep = new ReleaseTaskDep();
        $data = [
            'status' => ReleaseTaskEnum::STATUS_FAIL,
            'fail_at' => date('Y-m-d H:i:s'),
            'fail_msg' => $msg
        ];

        $releaseTaskDep->edit($taskId,$data);

        $contentData = [
            'status' =>  $resDetail->platform_id ? ContentEnum::STATUS_RELEASE_ADJUST : ContentEnum::STATUS_ADJUST,  //内部修改
            'latest_log' => "发布失败:{$msg}",
            'log_type' => 'error'
        ];

        $contentDep->edit($contentId,$contentData);

        $contentLogDep = new ContentLogDep();
        $logData = [
            'content_id' => $contentId,
            'description' => "发布失败:{$msg}",
        ];
        $contentLogDep->add($logData);


    }

}
